package com.example.gobang2.game;

import com.example.gobang2.config.WebSocketConfig;
import com.example.gobang2.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class Match {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    OnlineUserManager onlineUserManager;

    private Queue<User> normal = new LinkedList<>();
    private Queue<User> high = new LinkedList<>();
    private Queue<User> veryHigh = new LinkedList<>();
    @Autowired
    private RoomManager roomManager;

    public void add(User user){
        if(user.getScore()<=2000){
            synchronized (normal){
                normal.add(user);
                normal.notify();
            }
        }else if(user.getScore()>2000 && user.getScore()<=3000){
            synchronized (high){
                high.add(user);
                high.notify();
            }
        }else{
            synchronized (veryHigh){
                veryHigh.add(user);
                veryHigh.notify();
            }
        }
        System.out.println("[Match] 玩家："+user.getUsername()+"进入了匹配队列！");
    }

    public void remove(User user){
        if(user.getScore()<=2000){
            synchronized (normal){
                normal.remove(user);
            }
        }else if(user.getScore()>2000 && user.getScore()<=3000){
            synchronized (high){
                high.remove(user);
            }
        }else{
            synchronized (veryHigh){
                veryHigh.remove(user);
            }
        }
        System.out.println("[Match] 玩家："+user.getUsername()+"离开了匹配队列！");
    }

    private Match(){
        new Thread(() -> {
            while(true){
                handlerMatch(normal);
            }
        }).start();

        new Thread(() -> {
            while(true){
                handlerMatch(high);
            }
        }).start();

        new Thread(() -> {
            while(true){
                handlerMatch(high);
            }
        }).start();
    }

    private void handlerMatch(Queue<User> queue)  {
        synchronized (queue){
                try {
                    while(queue.size()<2) {
                        queue.wait();
                    }
                    User user1 = queue.poll();
                    User user2 = queue.poll();
                    System.out.println("[Math] 匹配出两个玩家：user1:"+user1.getUsername()+",user2:"+user2.getUsername());
                    WebSocketSession session1 = onlineUserManager.getSessionFromGameHall(user1.getUserId());
                    WebSocketSession session2 = onlineUserManager.getSessionFromGameHall(user2.getUserId());
                    onlineUserManager.enterGameRoom(user1.getUserId(), session1);
                    onlineUserManager.enterGameRoom(user2.getUserId(), session2);
                    if(session1==null) {
                        System.out.println("[Match]玩家："+user1.getUsername()+"退出！");
                        onlineUserManager.removeGameRoom(user1.getUserId());
                        return;
                    }
                    if(session2==null) {
                        System.out.println("[Match]玩家："+user2.getUsername()+"退出！");
                        onlineUserManager.removeGameRoom(user2.getUserId());
                        return;
                    }
                    if(session1==session2) {
                        System.out.println("[Match] 玩家重复登录"+user1.getUsername());
                        onlineUserManager.removeGameRoom(user1.getUserId());
                        return;
                    }

                    roomManager.addRoom(user1.getUserId(), user2.getUserId(), new Room());

                    MatchResponse response1 = new MatchResponse();
                    response1.setOk(true);
                    response1.setMessage("MatchSuccess");
                    session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));

                    MatchResponse response2 = new MatchResponse();
                    response2.setMessage("MatchSuccess");
                    response2.setOk(true);
                    session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));

                } catch (InterruptedException | IOException e) {
                    e.printStackTrace();
                }
        }
    }

}
